<template>
  <el-dialog
      v-model="dialogVisible"
      title="选择图标"
      width="800px"
      append-to-body
      top="5vh"
  >
    <div class="icon-container">
      <!-- 彩色复选框 -->
      <div class="color-toggle">
        <el-checkbox v-model="isColorful" @change="onColorfulChange">彩色显示</el-checkbox>
      </div>

      <!-- 搜索栏 -->
      <div class="search-bar">
        <el-input
            v-model="searchText"
            placeholder="搜索图标"
            clearable
        >
          <template #prefix>
            <el-icon><Search /></el-icon>
          </template>
        </el-input>
      </div>

      <!-- 图标列表 -->
      <el-scrollbar height="400px">
        <div class="icon-list">
          <div
              v-for="(component, name) in filteredIcons"
              :key="name"
              class="icon-item"
              :class="{ active: modelValue === name }"
              :style="{ color: getColor(name) }"
              @click="selectIcon(name)"
          >
            <el-icon>
              <component :is="component" />
            </el-icon>
            <span class="icon-name">{{ name }}</span>
          </div>
        </div>
      </el-scrollbar>
    </div>
  </el-dialog>
</template>

<script setup lang="ts">
import { ref, computed, watch } from 'vue'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
import { Search } from '@element-plus/icons-vue'

const props = defineProps<{
  modelValue: string
  visible: boolean
  color?: string // 父组件传入颜色（可选）
}>()

const emit = defineEmits(['update:modelValue', 'update:visible', 'update:color'])

const dialogVisible = computed({
  get: () => props.visible,
  set: (val) => emit('update:visible', val)
})

const searchText = ref('')
const isColorful = ref(!!props.color) // 如果父组件有颜色，默认彩色

// 图标颜色映射
const iconColors = ref<Record<string, string>>({})
if (props.color && props.modelValue) {
  iconColors.value[props.modelValue] = props.color
}

// 获取所有图标组件
const icons = ElementPlusIconsVue

// 根据搜索过滤图标
const filteredIcons = computed(() => {
  const entries = Object.entries(icons)
  if (!searchText.value) return icons
  return Object.fromEntries(
      entries.filter(([name]) => name.toLowerCase().includes(searchText.value.toLowerCase()))
  )
})

// 随机颜色生成
const randomColor = () =>
    '#' + Math.floor(Math.random() * 0xffffff).toString(16).padStart(6, '0')

// 彩色开关变化
const onColorfulChange = () => {
  if (isColorful.value) {
    Object.keys(filteredIcons.value).forEach((name) => {
      if (!iconColors.value[name]) iconColors.value[name] = randomColor()
    })
  } else {
    iconColors.value = {}
    if (props.modelValue) iconColors.value[props.modelValue] = ''
  }
}

// 获取图标颜色
const getColor = (name: string) => {
  return isColorful.value ? iconColors.value[name] || '' : ''
}

// 选中图标
const selectIcon = (iconName: string) => {
  if (isColorful.value && !iconColors.value[iconName]) {
    iconColors.value[iconName] = randomColor()
  }
  const color = iconColors.value[iconName] || ''
  emit('update:modelValue', iconName)
  emit('update:color', color)
  emit('update:visible', false)
}

// 父组件改变颜色或图标时同步
watch(
    () => props.color,
    (newColor) => {
      if (props.modelValue && newColor) iconColors.value[props.modelValue] = newColor
    }
)
</script>

<style scoped>
.icon-container {
  padding: 20px;
}

.color-toggle {
  margin-bottom: 10px;
}

.search-bar {
  margin-bottom: 20px;
}

.icon-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
  gap: 12px;
  padding: 12px;
}

.icon-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 16px 8px;
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.3s;
  border: 1px solid transparent;
}

.icon-item:hover {
  background-color: #ecf5ff;
  border-color: #409eff;
}

.icon-item.active {
  background-color: #ecf5ff;
  border-color: #409eff;
}

.icon-item .el-icon {
  font-size: 24px;
  margin-bottom: 8px;
}

.icon-name {
  font-size: 12px;
  color: #606266;
  word-break: break-all;
  text-align: center;
}

.icon-item.active .icon-name {
  color: inherit; /* 保持与图标颜色一致 */
}
</style>
